home *** CD-ROM | disk | FTP | other *** search
- ; PUSHD/POPD Ver. 1.0
- ;
- ; PUSHD saves the current directory on a stack. With the command
- ; POPD you change automatically back to that saved directory.
- ; The program, once loaded, stays in RAM and works as an
- ; extension of the command interpreter.
- ;
- ; Copyright (C) 1987 by Urs Zurbuchen, Switzerland
- ;
- ; You may freely distribute this program unless you
- ; include the sources and don't touch this header.
- ; Commercial usage is prohibited.
- ;
- ; Requirements:
- ; This program requires that the command editor CED
- ; (by C.J. Dunford) is installed.
- ;
- ; Restrictions:
- ; The directory stack has enough room for 5 entries.
- ; Each entry uses 64 bytes of RAM for storage.
- ;
- ; Usage: PUSHD
- ; POPD
- ;
- ; Assembly: MASM pushd; MASM popd;
- ; LINK pushd; LINK popd;
- ; EXE2BIN pushd pushd.com EXE2BIN popd popd.com
- ;
- ; Author: Urs Zurbuchen
- ;
- ; Date: February 9, 1987
- ;
- ; Revisions:
- ; Date Who What
- ;
- ;----------------------------------------------------------------------
-
- ; adjust the following global according to the processor used
- is_8088 equ 0 ; you won't have those fancy '286
- ; instructions if true
- if is_8088
- .8086
- else
- .286c ; this requires MASM 4.0
- endif
-
-
- ; some global constants
- cr equ 13 ; CarriageReturn
- lf equ 10 ; LineFeed
- space equ 32 ; (what do you guess :-)
- tab equ 9 ; Tabulator
-
- ; definitions for the CED interface
- ced equ 0ffh ; special DOS function for CED services
- enqueue equ 0 ; Subfunction to CED: enqueue command
- dequeue equ 1 ; Subfunction to CED: dequeue command
- ced_dos equ 1 ; CED parameter: command at DOS prompt
- ced_usr equ 2 ; CED parameter: command in user prg
-
- ; configurable constants
- entries equ 5 ; max. number of directories to push
-
- ; some program specific constants DON'T TOUCH THEM !!!!
- plength equ 65 ; pathname-buffer length (one entry)
- p2 equ 6
-
- ; here follows the program section
- cseg segment para public 'code'
- assume cs:cseg, ds:cseg, es:cseg
-
- ; initialization
- org 100h
-
- ;-----------------------
- ; Installation procedure
- ;-----------------------
- main proc far
- jmp install ; go to installation
-
- ; datastructures
- pbuf db entries * plength dup (?) ; pathname buffer
- pnum dw 0 ; "stack pointer"
-
- ; error messages
- msg1$ db 'pushd/popd: no parameters allowed', cr, lf, '$'
- msg2$ db 'pushd: stack full', cr, lf, '$'
- msg3$ db 'popd: stack empty', cr, lf, '$'
- msg4$ db 'pushd: cannot get current directory', cr, lf, '$'
- msg5$ db 'popd: cannot change to saved directory', cr, lf, '$'
-
- ;--------------------
- ; the PUSHD procedure
- ;--------------------
- pushd proc far
- mov byte ptr [si],cr ; null out the users input
- mov bp,dx
-
- psh_1: mov al,byte ptr es:[bp] ; test for parameters
- cmp al,cr ; end of input reached ?
- jz psh_ok
- inc bp
- cmp al,space ; space and tab are ok at the tail
- jz psh_1
- cmp al,tab
- jz psh_1
- jmp err_noparam ; any other char is bad enough
-
- psh_ok: push cs ; set data segment context
- pop ds
-
- mov ax,word ptr [pnum] ; is there any room left
- cmp ax,5
- jz err_noroom ; no: tell the user
-
- ; prepare for DOS call
- mov si,ax ; make room for first '\'
- if is_8088
- mov cl,p2 ; adjust for the different processors
- sal ax,cl
- else
- sal ax,p2
- endif
- add ax,offset pbuf ; compute buffer adress
- add si,ax ; DS:SI points to 65-byte buffer area
- inc si
- mov dl,0 ; indicates current drive
-
- push si
- mov ah,47h ; get current directory
- int 21h
- pop si
- jc err_fnerr1 ; tell user if we got an error
-
- inc word ptr [pnum] ; increment "stack pointer"
- mov byte ptr [si-1],'\' ; patch pathname
-
- ret ; exit to CED
-
- pushd endp
-
- ;-------------------
- ; the POPD procedure
- ;-------------------
- popd proc far
- mov byte ptr [si],cr ; null out the users input
- mov bp,dx
-
- pop_1: mov al,byte ptr es:[bp] ; test for parameters
- cmp al,cr ; end of input reached ?
- jz pop_ok
- inc bp
- cmp al,space ; space and tab are ok at the tail
- jz pop_1
- cmp al,tab
- jz pop_1
- jmp err_noparam ; any other char is bad enough
-
- pop_ok: push cs ; set data segment context
- pop ds
-
- mov ax,word ptr [pnum] ; is there any pathname on the stack
- or ax,ax
- jz err_empty ; no: tell the user
-
- dec ax ; prepare for DOS call
- mov dx,ax
- if is_8088
- mov cl,p2 ; adjust for the different processors
- sal ax,cl
- else
- sal ax,p2
- endif
- add ax,offset pbuf ; compute buffer adress
- add dx,ax ; DS:DX points to 65-byte buffer area
-
- mov ah,3bh ; change current directory
- int 21h
- jc err_fnerr2 ; tell user if we got an error
-
- dec word ptr [pnum] ; decrement "stack pointer"
- pop_end:
- ret ; exit to CED
- popd endp
-
-
- ;--------------
- ; error handler
- ;--------------
- error proc near
- err_noparam: ; no parameters allowed
- push cs
- pop ds
- mov dx,offset msg1$
- jmp err_common
-
- err_noroom: ; no more room for push
- mov dx,offset msg2$
- jmp err_common
-
- err_empty: ; stack is empty
- mov dx,offset msg3$
- jmp err_common
-
- err_fnerr1: ; error in getting current directory
- mov dx,offset msg4$
- jmp err_common
-
- err_fnerr2: ; error in changing to new directory
- mov dx,offset msg5$
- jmp err_common
-
- err_common: ; common point for error output
- mov ah,9 ; print string
- int 21h
- jmp pop_end
-
- error endp
-
- ;-------------------------------------------------------------------
- ; This is the installation routine. It queues the two commands above
- ; into the CED command editor. It terminates but leaves the command
- ; routines resident.
- ;-------------------------------------------------------------------
- install:
- push cs
- pop ds
- push ds
- pop es
-
- mov ah,ced ; request CED service from DOS
- mov al,enqueue ; enqueue a new command
- mov bl,ced_dos ; PUSHD is only active at DOS prompt
- mov si,offset pushd$ ; pointer to command name
- mov di,offset pushd ; pointer to service routine
- int 21h
- jnc inst_next ; skip error handler
-
- mov dx,offset msg_inst1$ ; only error 8 is possible here
- inst_err:
- mov ah,9 ; print string
- int 21h
- int 20h ; exit without staying resident
-
- inst_next:
- mov ah,ced ; request CED service once more
- mov al,enqueue ; enqueue a new command
- mov bl,ced_dos ; POPD is only active at the DOS prompt
- mov si,offset popd$ ; pointer to command name
- mov di,offset popd ; pointer to service routine
- int 21h
- jnc inst_ok ; no error: exit
-
- mov ah,ced ; dequeue pushd if we can't
- mov al,dequeue ; install popd
- mov si,offset popd$ ; pointer to command name
- int 21h ; no error possible for dequeue
- mov dx,offset msg_inst2$ ; now, tell the user about the error
- jmp inst_err
-
- inst_ok:
- mov dx,offset install ; ok: terminate/resident
- int 27h
- main endp
-
- ; messages for installation procedure
- msg_inst1$ db 'install pushd: CED command list full', cr, lf, '$'
- msg_inst2$ db 'install popd: CED command list full', cr, lf, '$'
-
- ; command names
- pushd$ db 'pushd',cr
- popd$ db 'popd',cr
-
- cseg ends
- end main